﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenCLNet;

namespace GPUTracer
{
    public static class Helper
    {
        public static void Float4ToByteArray(byte[] result, Float4 vector, ref int c)
        {
            Buffer.BlockCopy(BitConverter.GetBytes(vector.S0), 0, result, c, 4);
            c += 4;
            Buffer.BlockCopy(BitConverter.GetBytes(vector.S1), 0, result, c, 4);
            c += 4;
            Buffer.BlockCopy(BitConverter.GetBytes(vector.S2), 0, result, c, 4);
            c += 4;
            Buffer.BlockCopy(BitConverter.GetBytes(vector.S3), 0, result, c, 4);
            c += 4;
        }

        //Vector Helper functions:

        public static Float4 Add(this Float4 a, Float4 b)
        {
            return new Float4(a.S0 + b.S0, a.S1 + b.S1, a.S2 + b.S2, a.S3 + b.S3);
        }

        public static Float4 Sub(this Float4 a, Float4 b)
        {
            return new Float4(a.S0 - b.S0, a.S1 - b.S1, a.S2 - b.S2, a.S3 - b.S3);
        }

        public static Float4 Times(this Float4 a, Float4 b)
        {
            return new Float4(a.S0 * b.S0, a.S1 * b.S1, a.S2 * b.S2, a.S3 * b.S3);
        }

        public static float Dot(Float4 a, Float4 b)
        {
            return (a.S0 * b.S0) + (a.S1 * b.S1) + (a.S2 * b.S2);
        }

        public static float Magnitude(this Float4 v)
        {
            return (float) Math.Sqrt(Dot(v, v));
        }

        public static Float4 Times(this Float4 v, float scalar)
        {
            return new Float4(scalar * v.S0, scalar * v.S1, scalar * v.S2, scalar * v.S3);
        }

        public static Float4 Normalize(this Float4 v)
        {
            float mag = Magnitude(v);
            float div = mag == 0 ? float.MaxValue : 1 / mag;
            return v.Times(div);
        }

        public static Float4 Cross(Float4 a, Float4 b)
        {
            return new Float4(((a.S1 * b.S2) - (a.S2 * b.S1)),
                     ((a.S2 * b.S0) - (a.S0 * b.S2)),
                     ((a.S0 * b.S1) - (a.S1 * b.S0)), 0);
        }

        public static float Length(this Float4 ldis)
        {
            return (float) Math.Sqrt(ldis.S0*ldis.S0 + ldis.S1*ldis.S1 + ldis.S2*ldis.S2 + ldis.S3*ldis.S3);
        }
    }
}
